package api

import (
	"com.yy.api/agent/service"
	argsAg "com.yy.api/common/client/agent"
	replyAg "com.yy.api/common/client/agent"
	"com.yy.api/common/logger"
	"com.yy.api/common/pojo/dto"
)

type AgentApi interface {
	CreateContainer(args *argsAg.CreateContainerArgs, reply *replyAg.CreateContainerReply) error
	StartContainer(args *argsAg.StartContainerArgs, reply *replyAg.StartContainerReply) error
	InspectContainer(args *argsAg.InspectContainerArgs, reply *replyAg.InspectContainerReply) error
	PullImage(args *argsAg.PullImageArgs, reply *replyAg.PullImageReply) error
	ListContainers(args *argsAg.ListContainersArgs, reply *replyAg.ListContainersReply) error
	ReleaseContainer(args *argsAg.ReleaseContainerArgs, reply *replyAg.ReleaseContainerReply) error
	HasContainer(args *argsAg.HasContainerArgs, reply *replyAg.HasContainerReply) error
}

type Agent struct {
	Service service.Podman
}

func NewAgent() Agent {
	podmanService := service.NewPodmanService()
	if podmanService == nil {
		logger.Default.Errorf("Fail to initialize agent connection")
	}
	return Agent{
		Service: podmanService,
	}
}

func (a *Agent) CreateContainer(args *argsAg.CreateContainerArgs, reply *replyAg.CreateContainerReply) error {
	logger.Default.Infof("Agent CreateContainer... ,args:", args)
	result, err := a.Service.CreateContainer(args.CreateContainerParam)
	if err != nil {
		logger.Default.Errorf("%v", err)
		return err
	}
	reply.CreateContainerDto = dto.CreateContainerDto(result)
	logger.Default.Infof("Agent CreateContainer... ,reply:", reply)
	return nil
}

func (a *Agent) StartContainer(args *argsAg.StartContainerArgs, reply *replyAg.StartContainerReply) error {
	logger.Default.Infof("Agent StartContainer... ,args:", args)
	containerId := args.StartContainerParam.GetContainerId()
	err := a.Service.StartContainer(containerId)
	if err != nil {
		return err
	}
	return nil
}

func (a *Agent) InspectContainer(args *argsAg.InspectContainerArgs, reply *replyAg.InspectContainerReply) error {
	logger.Default.Infof("Agent InspectContainer... ,args:", args)
	nameOrId := args.InspectContainerParam.GetContainerIdOrName()
	result, err := a.Service.InspectContainer(nameOrId)
	if err != nil {
		return err
	}
	reply.InspectContainerDataDto = dto.InspectContainerDataDto(result)
	logger.Default.Infof("Agent InspectContainer... ,reply:", reply)
	return nil
}

func (a *Agent) PullImage(args *argsAg.PullImageArgs, reply *replyAg.PullImageReply) error {
	logger.Default.Infof("Agent PullImage... ,args:", args)
	rowImage := args.PullImageParam.GetRowImage()
	return a.Service.PullImage(rowImage)
}

func (a *Agent) ListContainers(args *argsAg.ListContainersArgs, reply *replyAg.ListContainersReply) error {
	logger.Default.Infof("Agent ListContainers... ")
	result, err := a.Service.ListContainers(args.ListContainerParam)
	if err != nil {
		return err
	}
	reply.ListContainersDto = dto.ListContainersDto(result)
	logger.Default.Infof("Agent ListContainers... ,reply", reply)
	return nil
}
func (a *Agent) ReleaseContainer(args *argsAg.ReleaseContainerArgs, reply *replyAg.ReleaseContainerReply) error {
	logger.Default.Infof("Agent ReleaseContainer... ,args:", args)
	nameOrId := args.ReleaseContainerParam.GetContainerIdOrName()
	result, err := a.Service.ReleaseContainer(nameOrId)
	if err != nil {
		return err
	}
	reply.ReleaseContainerDto = dto.ReleaseContainerDto(result)
	logger.Default.Infof("Agent ReleaseContainer... ,reply:", reply)
	return nil
}
func (a *Agent) HasContainer(args *argsAg.HasContainerArgs, reply *replyAg.HasContainerReply) error {
	logger.Default.Infof("Agent HasContainer... ,args:", args)
	nameOrId := args.HasContainerParam.GetContainerIdOrName()
	result, err := a.Service.HasContainer(nameOrId)
	if err != nil {
		logger.Default.Errorf("%v", err)
		return err
	}
	reply.HasContainerDto = dto.HasContainerDto(result)
	logger.Default.Infof("Agent HasContainer... ,reply:", reply)
	return nil
}

func (a *Agent) HealthCheckContainer(args *argsAg.HealthCheckContainerArgs, reply *replyAg.HealthCheckContainerReply) error {
	logger.Default.Infof("Agent HealthCheckContainer... ,args:", args)
	nameOrId := args.HealthCheckContainerParam.GetContainerIdOrName()
	result, err := a.Service.HealthCheckContainer(nameOrId)
	if err != nil {
		logger.Default.Errorf("%v", err)
		return err
	}
	reply.HealthCheckContainerDto = dto.HealthCheckContainerDto(result)
	logger.Default.Infof("Agent HealthCheckContainer...,reply:", reply)
	return nil
}
